<template>
  <div class="canvas_box" id="canvas_box">
    <div class="content_box" id="content_box">
      <!--style="background: rgba(225, 225, 225, .1)"-->
      <!--宽度是193 * 7 + 100-->
      <div
        style="position: relative;margin-left: 50%;margin-right: 50%;"
        :width="cWidth"
        :height="cHeight"
        :style="'left:' +  (- cWidth / 2 ) + 'px'"
      >
        <canvas ref="mycanvas" :width="cWidth" :height="cHeight"></canvas>
        <canvas
          ref="canvas"
          :width="cWidth"
          :height="cHeight"
          :style="isBtn ? 'cursor: pointer' : 'cursor: default'"
          style="position: absolute;left: 0;top: 0;z-index: 999"
          @mousedown="canvasDown($event)"
          @mouseup="canvasUp($event)"
          @mousemove="canvasMove($event)"
          @touchstart="canvasDown($event)"
          @touchend="canvasUp($event)"
          @touchmove="canvasMove($event)"
        ></canvas>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'canvasHive',
  data () {
    return {
      cWidth: null,
      cHeight: null,
      isBtn: false,
      buttons: [],
      isMoveDown: null,
      mycanvas: null,
      canvas: null,
      cIsLoad: false,
      ctx: null,
      hctx: null,
    }
  },
  mounted () {
    // this.cWidth = document.getElementsByTagName('body')[0].clientWidth
    // this.cHeight = document.getElementById('content_box').clientHeight
    this.cWidth = document.getElementById('content_box').clientWidth
    this.cHeight = document.getElementById('content_box').clientHeight
    let that = this
    that.drawBtnInit()

    setTimeout(function () {
      that.cIsLoad = true
    }, 1000)
    // 添加对窗口大小的监听,同时需要调用绘制函数
    window.addEventListener('resize', function () {
      that.cWidth = document.getElementById('content_box').clientWidth
      that.cHeight = document.getElementById('content_box').clientHeight
      that.ctx.fillRect(0, 0, that.cWidth, that.cHeight)
      that.hctx.fillRect(0, 0, that.cWidth, that.cHeight)
      that.drawBtnInit()
    })
  },
  methods: {
    // 绘制按钮函数
    drawBtnInit () {
      const that = this
      that.mycanvas = that.$refs.mycanvas // 指定canvas
      that.ctx = that.mycanvas.getContext('2d') // 设置2D渲染区域
      that.canvas = that.$refs.canvas // 指定canvas
      that.hctx = that.canvas.getContext('2d') // 设置2D渲染区域


      let btns1 = [
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 0, y: 20 }, isRealBtn: false },
        // { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/qqcutTect.png'), offset: { x: 0, y: 20 } },
        { text: 'xx', tag: {}, path: 'Index', icon: require('../../assets/svg-for-middleware/Elasticsearch.svg'), offset: { x: 50, y: 20 }, isRealBtn: true },
        { text: 'xx', tag: {}, path: 'Integrated', icon: require('../../assets/svg-for-middleware/Kafka.svg'), offset: { x: 50, y: 20 }, isRealBtn: true }, // 图标原图不是居中，补偿xy
        { text: 'xx', tag: {}, path: 'KeyManagement', icon: require('../../assets/svg-for-middleware/MySQL (1).svg'), offset: { x: 50, y: 20 }, isRealBtn: true },
        { text: 'xx', tag: {}, path: 'Security', icon: require('../../assets/svg-for-middleware/Spark 2.svg'), offset: { x: 50, y: 20 }, isRealBtn: true },
        { text: 'xx', tag: {}, path: 'Contradiction', icon: require('../../assets/svg-for-middleware/Zookeeper (1).svg'), offset: { x: 50, y: 20 }, isRealBtn: true },
        { text: 'xx', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/logstash.svg'), offset: { x: 50, y: 20 }, isRealBtn: true },
        { text: 'xx', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/neo4j.svg'), offset: { x: 50, y: 20 }, isRealBtn: true },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 0, y: 20 }, isRealBtn: false },
      ]
      let btns2 = [
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: 'xx', tag: {}, path: 'myProtectionLineX', icon: require('../../assets/svg-for-middleware/spring.svg'), offset: { x: 50, y: 20 }, isRealBtn: true },
        { text: 'xx', tag: {}, path: 'School', icon: require('../../assets/svg-for-middleware/nginx.svg'), offset: { x: 50, y: 20 }, isRealBtn: true },
        { text: 'xx', tag: {}, path: 'OA', icon: require('../../assets/svg-for-middleware/redis (1).svg'), offset: { x: 50, y: 20 }, isRealBtn: true },
        { text: 'xx', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/spring-logo.svg'), offset: { x: 50, y: 20 }, isRealBtn: true },
        { text: 'xx', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/表格.svg'), offset: { x: 50, y: 20 }, isRealBtn: true },
        { text: 'xx', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/MySQL.svg'), offset: { x: 50, y: 20 }, isRealBtn: true },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
      ]
      let btns3 = [
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
      ]
      let btns4 = [
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
        { text: '', tag: {}, path: 'x', icon: require('../../assets/svg-for-middleware/透明图片.png'), offset: { x: 50, y: 20 }, isRealBtn: false },
      ]
      // 1,56  96.5,1   193,96.5   193,162   96.5,221  1,162
      // 96.5, 110.5
      // 画按钮
      for (let i = 0; i < btns4.length; i++) {  // 第一行
        let baseX = -50 + i * 193
        let baseY = 50
        that.btnAdd(baseX, baseY, btns4[i].text, btns4[i].tag, btns4[i].path, btns4[i].icon, btns4[i].offset, btns4[i].isRealBtn)
      }
      for (let i = 0; i < btns1.length; i++) { // 第二行
        let baseX = 50 + i * 193
        let baseY = 220
        that.btnAdd(baseX, baseY, btns1[i].text, btns1[i].tag, btns1[i].path, btns1[i].icon, btns1[i].offset, btns1[i].isRealBtn)
      }
      for (let i = 0; i < btns2.length; i++) {  // 第三行
        // let baseX = -145 + 96.5 + i * 193
        let baseX = -50 + i * 193
        let baseY = 390
        that.btnAdd(baseX, baseY, btns2[i].text, btns2[i].tag, btns2[i].path, btns2[i].icon, btns2[i].offset, btns2[i].isRealBtn)
      }
      for (let i = 0; i < btns3.length; i++) {  // 第四行
        let baseX = 50 + i * 193
        let baseY = 560
        that.btnAdd(baseX, baseY, btns3[i].text, btns3[i].tag, btns3[i].path, btns3[i].icon, btns3[i].offset, btns3[i].isRealBtn)
      }

    },
    drawImage (x, y, w, h, icon, onSuccess) {
      let _this = this
      // 创建新的图片对象
      let img = new Image()
      // 指定图片的URL

      // img.src = imgSrc
      img.src = icon // 图标会渲染两次，故注释。不明确上方imgSrc是什么，插件亦或是定义的方法、变量
      // 浏览器加载图片完毕后再绘制图片
      // _this.ctx.drawImage(img, x, y, w, h)
      img.onload = function () {
        // 以Canvas画布上的坐标( x, y)为起始点，绘制图像
        // _this.ctx.drawImage(img, x, y, w, h) // 注释掉此处，解决图标渲染两次的问题,此处为canvas绘制图片的方法

        if (onSuccess) {
          onSuccess()
        }
      }
    },
    drawIcon (x, y, maxX, maxH, icon, offset) {
      // console.log(offset)
      let _this = this
      // 创建新的图片对象
      let img = new Image()
      // 指定图片的URL
      img.src = icon
      // 浏览器加载图片完毕后再绘制图片
      img.onload = function () {
        // 以Canvas画布上的坐标( x, y)为起始点，绘制图像
        let w = img.width
        let h = img.height
        if (maxX > img.width) {
          x = x + (maxX - img.width) / 2
        } else {
          w = maxX
        }
        if (maxH > img.height) {
          y = y + (maxH - img.height) / 2
        } else {
          h = maxH
        }
        debugger
        _this.ctx.drawImage(img, x + offset.x, y + offset.y, w, h)

      }
    },
    drawText (x, y, text) {
      let _this = this
      _this.ctx.font = '18px bold 黑体'
      // 设置颜色
      _this.ctx.fillStyle = 'green'
      // 设置水平对齐方式
      _this.ctx.textAlign = 'center'
      // 设置垂直对齐方式
      _this.ctx.textBaseline = 'middle'
      // 绘制文字（参数：要写的字，x坐标，y坐标）

      _this.ctx.fillText(text, x, y)
    },
    drawlowLevelPath (x, y, n, r) {
      let i, ang
      ang = Math.PI * 2 / n // 旋转的角度
      this.ctx.save() // 保存状态
      // this.hctx.fillStyle = 'cyan' // 填充红色，半透明 阴影效果
      // this.ctx.strokeStyle = 'green' // 填充边框色
      // this.hctx.fillStyle = 'rgba(255,255,255,0.1)' // 填充红色，半透明 阴影效果
      this.ctx.fillStyle = 'transparent' // 填充红色，半透明 阴影效果
      this.ctx.strokeStyle = 'rgba(28, 182, 255, .3)' // 填充边框色
      this.ctx.lineWidth = 6 // 设置线宽
      this.ctx.translate(x, y) // 原点移到x,y处，即要画的多边形中心
      this.ctx.moveTo(0, -r) // 据中心r距离处画点
      this.ctx.beginPath()
      for (i = 0; i < n; i++) {
        this.ctx.rotate(ang) // 旋转
        this.ctx.lineTo(0, -r) // 据中心r距离处连线
      }
      this.ctx.closePath()
      this.ctx.stroke()
      this.ctx.fill()
      this.ctx.restore() // 返回原始状态

    },
    drawLinearGradient () {
      let grd = this.ctx.createLinearGradient(0, 0, this.cWidth, 0);
      grd.addColorStop(0, "white");
      grd.addColorStop(0.5, "#88ded2");
      grd.addColorStop(1, "white");

      // 填充渐变
      this.ctx.fillStyle = grd;
      this.ctx.fillRect(0, 0, this.cWidth, this.cHeight);
    },
    drawPath (x, y, n, r) {
      let i, ang
      ang = Math.PI * 2 / n // 旋转的角度
      this.hctx.save() // 保存状态
      // this.hctx.fillStyle = 'cyan' // 填充红色，半透明 阴影效果
      // this.hctx.strokeStyle = 'green' // 填充边框色
      this.hctx.fillStyle = 'rgba(255,255,255,0.3)' // 填充红色，半透明 阴影效果
      // this.hctx.fillStyle = 'transparent' // 填充红色，半透明 阴影效果
      this.hctx.strokeStyle = 'rgba(23, 97, 105, .8)' // 填充边框色
      this.hctx.lineWidth = 6 // 设置线宽
      this.hctx.translate(x, y) // 原点移到x,y处，即要画的多边形中心
      this.hctx.moveTo(0, -r) // 据中心r距离处画点
      this.hctx.beginPath()
      for (i = 0; i < n; i++) {
        this.hctx.rotate(ang) // 旋转
        this.hctx.lineTo(0, -r) // 据中心r距离处连线
      }
      this.hctx.closePath()
      this.hctx.stroke()
      this.hctx.fill()
      this.hctx.restore() // 返回原始状态
    },
    getBtnObj (e) {
      let offsetX = e.offsetX
      let offsetY = e.offsetY
      if (e.type === 'touchstart' || e.type === 'touchend') {
        // touch 没有 offsetX Y
        let tX = e.changedTouches[0].clientX
        let tY = e.changedTouches[0].clientY
        let rect = this.canvas.getBoundingClientRect()
        offsetX = tX - rect.x
        offsetY = tY - rect.y
      }
      if (e.type !== 'mousemove') {
        console.log('=====修正offsetX=', offsetX)
        console.log('=====修正offsetY=', offsetY)
      }
      let obj = null
      for (let i = 0; i < this.buttons.length; i++) {
        // 判断在哪个个button
        let find = true
        for (let j = 0; j < this.buttons[i].points.length; j++) {
          // 如果不是最后一个，和下一个点组合，如果是最后一个，和第一个组合
          let res = false
          if (j === this.buttons[i].points.length - 1) {
            res = this.judgeIntersect(offsetX, offsetY, this.buttons[i].center.x, this.buttons[i].center.y, this.buttons[i].points[j].x, this.buttons[i].points[j].y, this.buttons[i].points[0].x, this.buttons[i].points[0].y)
          } else {
            res = this.judgeIntersect(offsetX, offsetY, this.buttons[i].center.x, this.buttons[i].center.y, this.buttons[i].points[j].x, this.buttons[i].points[j].y, this.buttons[i].points[j + 1].x, this.buttons[i].points[j + 1].y)
          }
          if (res) {
            find = false
            break
          }
        }
        if (find) {
          // console.log('================' + i)
          obj = this.buttons[i]
          break
        }
      }
      return obj
    },
    // 判断两条线是否相交
    judgeIntersect (x1, y1, x2, y2, x3, y3, x4, y4) {
      if (!(Math.min(x1, x2) <= Math.max(x3, x4) && Math.min(y3, y4) <= Math.max(y1, y2) && Math.min(x3, x4) <= Math.max(x1, x2) && Math.min(y1, y2) <= Math.max(y3, y4))) {
        return false
      }
      let u, v, w, z
      u = (x3 - x1) * (y2 - y1) - (x2 - x1) * (y3 - y1)
      v = (x4 - x1) * (y2 - y1) - (x2 - x1) * (y4 - y1)
      w = (x1 - x3) * (y4 - y3) - (x4 - x3) * (y1 - y3)
      z = (x2 - x3) * (y4 - y3) - (x4 - x3) * (y2 - y3)
      return (u * v <= 0.00000001 && w * z <= 0.00000001)
    },
    btnAdd (baseX, baseY, text, tag, path, icon, offset, isRealBtn) {
      let _this = this
      this.drawImage(baseX, baseY, 193, 221, icon, () => {
        _this.drawLinearGradient()
        setTimeout(() => {

          _this.drawIcon(baseX, baseY, 80, 80, icon, offset)
          _this.drawText(baseX + 90.5, baseY + 135, text)
          // _this.drawPath(baseX + 96.5, baseY + 160, 6, 102)
          // _this.drawPath(baseX + 95, baseY + 75, 6, 102)
          _this.drawlowLevelPath(baseX + 95, baseY + 75, 6, 102)
        }, 500)

      })
      this.buttons.push({
        text: text,
        tag: tag,
        path: path,
        basePoint: { x: baseX, y: baseY },
        center: { x: baseX + 96.5, y: baseY + 110.5 },
        points: [{ x: baseX + 1, y: baseY + 56 }, { x: baseX + 96.5, y: baseY + 1 }, { x: baseX + 193, y: baseY + 96.5 }, { x: baseX + 193, y: baseY + 162 }, { x: baseX + 96.5, y: baseY + 221 }, { x: baseX + 1, y: baseY + 162 }],
        isRealBtn // 增加一个属性，由于标记是否是真实的按钮
      })
    },
    // 鼠标移动时绘制
    canvasMove (e) {
      // console.log('=canvasMove=======', e)
      // client是基于整个页面的坐标，offset是cavas距离pictureDetail顶部以及左边的距离
      // let canvasX = e.clientX - e.target.parentNode.offsetLeft
      // let canvasY = e.clientY - e.target.parentNode.offsetTop
      // this.ctx.stroke()
      if (this.cIsLoad) {
        let btn = this.getBtnObj(e)
        // console.log(btn)
        if (btn) {
          this.isBtn = true
          // 缓存图片前如果有已经缓存的图片先加载，避免光圈不能消失
          // if (this.cContentImg) {
          // this.hctx.clearRect(0, 0, this.cWidth, this.cHeight)
          // this.drawCanvasImage()
          // this.ctx.putImageData(this.cContentImg, 0, 0)
          // }
          // 缓存图片
          // this.cContentImg = this.ctx.getImageData(0, 0, this.cWidth, this.cHeight) // this.mycanvas.toDataURL('image/png') //
          this.hctx.clearRect(0, 0, this.cWidth, this.cHeight)
          if (!btn.isRealBtn) { return }
          this.drawPath(btn.center.x, btn.center.y - 36, 6, 102) // 画一个半径为40的六边形
        } else {
          this.isBtn = false
          this.hctx.clearRect(0, 0, this.cWidth, this.cHeight)
          // if (this.cContentImg) {
          // this.ctx.clearRect(0, 0, this.cWidth, this.cHeight)
          // this.drawCanvasImage()
          // this.ctx.putImageData(this.cContentImg, 0, 0)
          // }
        }
      }
    },
    // 鼠标抬起
    canvasUp (e) {
      // console.log('=======canvasUp=======', e)
      let btn = this.getBtnObj(e)
      if (btn) {
        this.menuClick(btn.text, btn.path)
      }
      // console.log('=======canvasUp=======', btn)
      this.isMoveDown = false
    },
    menuClick (text, path) {
      console.log(text)
    },
    canvasDown (e) {
      console.log(e)
    }
  }

}
</script>

<style  scoped>
.canvas_box {
  background-color: #f5f5f5;
}
.content_box {
  margin: 10px auto;
  height: 97%;
  box-shadow: 2px 2px 5px 5px #999;
  width: 98%;
  background-color: #ffffff;
  overflow: hidden;
}
</style>